package com.fbinggun.fbinggunutil.statistics;

import com.alibaba.fastjson.JSONObject;
import com.fbinggun.fbinggunutil.API.TiemUtil;
import com.fbinggun.fbinggunutil.statistics.datatype.DoubleInfo;
import com.fbinggun.fbinggunutil.statistics.datatype.IntInfo;
import com.fbinggun.fbinggunutil.statistics.datatype.LongInfo;
import com.fbinggun.fbinggunutil.statistics.datatype.StringInfo;


import java.util.HashMap;
import java.util.Map;

public abstract class StatisticsInfo<T> {

    protected T t;
    public static Map<Class,StatisticsInfo> classClassMap= new HashMap<>();
    Long clockTime;
    Long firstClock;
    String id;
    protected StatisticsInfo(String id,T t) {
        this.id=id;
        this.t = t;
        this.clockTime= TiemUtil.date();
        this.firstClock=TiemUtil.date();
    }

    public void setFirstClock(Long firstClock) {
        this.firstClock = firstClock;
    }

    public String getId() {
        return id;
    }

    protected StatisticsInfo(String id, JSONObject jsonObject){
        this.id=id;
        t = (T) jsonObject.get("Value");
        clockTime=jsonObject.getLong("ClockTime");
        firstClock=jsonObject.getLong("FirstClock");
    }

    protected abstract StatisticsInfo<T> copy(String id,JSONObject jsonObject);
    protected abstract StatisticsInfo<T> copy(String id,T t);



    protected Long getClockTime() {
        return clockTime;
    }
    protected Long getFirstClock() {
        return firstClock;
    }


    protected void setClockTime(Long clockTime) {
        this.clockTime = clockTime;
    }



    protected JSONObject toJson(){
        JSONObject json = new JSONObject();
        json.put("Value",getValue());
        json.put("ClockTime",getClockTime());
        json.put("FirstClock",getFirstClock());
        json.put("Class",this.getClass().getName());
        return json;
    }



    public static StatisticsInfo getInstance(String name, JSONObject jsonObject)  {
        try {
            Class c=Class.forName(jsonObject.getString("Class"));
            StatisticsInfo info= classClassMap.get(c);
            if(info!=null){
                return  info.copy(name,jsonObject);
            }

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    public static <T> StatisticsInfo<T> getInstance(String name,T t,Class c)  {
        StatisticsInfo<T> info= classClassMap.get(c);
        if(info!=null){
            return  info.copy(name,t);
        }
        return null;
    }



    public static <T> void register(StatisticsInfo<T> info){
        classClassMap.put(info.getClass(),info);
    }

    protected void setValue(T t){
        this.t=t;
    }
    protected abstract void setSValue(String t);
    protected abstract   void addValue(T t);
    protected abstract   void addSValue(String t);


    public abstract String getPlaceholder();
    protected T getValue(){
        return t;
    }

    protected static enum InfoType{
        LONG(LongInfo.class,Long.class),
        INT(IntInfo.class,Integer.class),
        DOUBLE(DoubleInfo.class,Double.class),
        STRING(StringInfo.class,String.class),
        BOOLEAN(Boolean.class,Boolean.class);
        Class c;
        Class tC;
        InfoType(Class c,Class tc) {
            this.c=c;
            this.tC=tc;
        }

        public Class gettC() {
            return tC;
        }

        public Class getC() {
            return c;
        }

        public static <T> InfoType getInfoClass(T t){
            Class c= t.getClass();
            for(InfoType infoType:InfoType.values()){
                if(infoType.gettC()==c){
                    return infoType;
                }
            }
            return null;
        }
    }


}
